package class61To70;

import java.io.*;
import java.util.Arrays;

public class TwoWaySearch {

    public static int MAX_N = 41;

    public static int MAX_M = 1 << 20;

    public static long[] lsum = new long[MAX_M];

    public static long[] rsum = new long[MAX_M];

    public static long[] arr = new long[MAX_N];

    public static int n;

    public static long w;

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StreamTokenizer in = new StreamTokenizer(br);
        PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        while (in.nextToken() != StreamTokenizer.TT_EOF) {
            n = (int) in.nval;
            in.nextToken();
            w = (long) in.nval;
            for (int i = 0; i < n; i++) {
                in.nextToken();
                arr[i] = (long) in.nval;
            }
            out.println(compute());
        }
        out.flush();
        out.close();
        br.close();
    }

    private static long compute() {
        int lsize = f(0, n >> 1, 0, w, lsum, 0);
        int rsize = f(n >> 1, n, 0, w, rsum, 0);
        Arrays.sort(lsum, 0, lsize);
        Arrays.sort(rsum, 0, rsize);
        long ans = 0;
        for (int i = lsize - 1, j = 0; i >= 0; i--) {
            while (j < rsize && lsum[i] + rsum[j] <= w) {
                j++;
            }
            ans += j;
        }
        return ans;
    }

    public static int f(int l, int r, long s, long w, long[] ans, int end) {
        if (s > w) {
            return end;
        }
        if (l == r) {
            ans[end++] = s;
        } else {
            end = f(l + 1, r, s, w, ans, end);
            end = f(l + 1, r, s + arr[l], w, ans, end);
        }
        return end;
    }

    public static int fill;

    public static int minAbsDifference(int[] nums, int goal) {
        int n = nums.length;
        long min = 0;
        long max = 0;
        for (int i = 0; i < n; i++) {
            if (nums[i] >= 0) {
                max += nums[i];
            } else {
                min += nums[i];
            }
        }
        if (max < goal) {
            return (int) Math.abs(max - goal);
        }
        if (min > goal) {
            return (int) Math.abs(min - goal);
        }
        // 原始数组排序，为了后面递归的时候，还能剪枝
        // 常数优化
        Arrays.sort(nums);
        fill = 0;
        collect(nums, 0, n >> 1, 0, lsum);
        int lsize = fill;
        fill = 0;
        collect(nums, n >> 1, n, 0, rsum);
        int rsize = fill;
        Arrays.sort(lsum, 0, lsize);
        Arrays.sort(rsum, 0, rsize);
        long ans = Math.abs(goal);
        for (int i = 0, j = rsize - 1; i < lsize; i++) {
            while (j > 0 && Math.abs(goal - lsum[i] - rsum[j - 1]) <= Math.abs(goal - lsum[i] - rsum[j])) {
                j--;
            }
            ans = Math.min(ans, Math.abs(goal - lsum[i] - rsum[j]));
        }
        return (int) ans;
    }

    public static void collect(int[] nums, int i, int e, int s, long[] sum) {
        if (i == e) {
            sum[fill++] = s;
        } else {
            // nums[i.....]这一组，相同的数字有几个
            int j = i + 1;
            while (j < e && nums[j] == nums[i]) {
                j++;
            }
            // nums[ 1 1 1 1 1 2....
            //       i         j
            for (int k = 0; k <= j - i; k++) {
                // k = 0个
                // k = 1个
                // k = 2个
                collect(nums, j, e, s + k * nums[i], sum);
            }
        }
    }
}
